use std::sync::mpsc::SyncSender;

use glam::DVec3;

use crate::*;

pub fn demo1(tx: SyncSender<(usize, DVec3)>) -> (Renderer, Box<dyn Hitable>) {
    let mut scene = Hitables::default();

    // create materials
    let mat_ground = LambertMaterial::new(dvec3(0.5, 0.5, 0.5));
    scene.add(Sphere::new(dvec3( 0.0, -1000.0, 0.0), 1000.0, mat_ground));
    
    for i in -11..11 {
        for j in -11..11 {
            let mat_random = random_standard_uniform();

            let center = dvec3(
                i as f64 + 0.9 * random_standard_uniform(),
                0.2,
                j as f64 + 0.9 * random_standard_uniform(),
            );

            if (center - dvec3(4.0, 0.2, 0.0)).length() > 0.9 {
                // diffuse
                if mat_random < 0.8 {
                    let albedo = random_vec3_range(0.0, 1.0);
                    let mat = LambertMaterial::new(albedo);
                    scene.add(Sphere::new(center, 0.2, mat));
                }
                // metal
                else if mat_random < 0.95 {
                    let albedo = random_vec3_range(0.0, 1.0);
                    let fuzz = random_range(0.0, 0.5);
                    let mat = MetalMaterial::new(albedo, fuzz);
                    scene.add(Sphere::new(center, 0.2, mat));
                }
                // glass
                else {
                    let mat = DielectricMaterial::new(1.5);
                    scene.add(Sphere::new(center, 0.2, mat));
                }
            }
        }
    }
    
    let mat = LambertMaterial::new(dvec3(0.4, 0.2, 0.1));
    scene.add(Sphere::new(DVec3::new( -4.0, 1.0, 0.0), 1.0, mat));

    let mat = DielectricMaterial::new(1.5);
    scene.add(Sphere::new(DVec3::new( 0.0, 1.0, 0.0), 1.0, mat));

    let mat = MetalMaterial::new(dvec3(0.7, 0.6, 0.5), 0.0);
    scene.add(Sphere::new(DVec3::new( 4.0, 1.0, 0.0), 1.0, mat));


    let renderer = RendererBuilder::new(tx)
        .camera(
            dvec3(13.0, 2.0, 3.0), 
            dvec3(0.0, 0.0, -1.0), 
            dvec3(0.0, 1.0, 0.0), 
            20.0
        )
        .max_depth(10)
        .sample_count(10)
        .build();

    (renderer, Box::new(BVHNode::from(scene)))
}
